package com.biquge.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.biquge.common.ThreadPoolUtils;
import com.biquge.dao.NovelCopyDao;
import com.biquge.dao.NovelDao;
import com.biquge.entity.Novel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 爬虫对象
 *
 * @author wangmeng
 * @since 2021/12/11
 */
@Component
@Slf4j
public class novelReptile {

    public novelReptile() {
    }

    public novelReptile(Integer chapterIndex, String chapterName, NovelDao novelDao, NovelCopyDao novelCopyDao, int retry) {
        this.chapterIndex = chapterIndex;
        this.chapterName = chapterName;
        this.novelDao = novelDao;
        this.novelCopyDao = novelCopyDao;
        this.retry = retry;
    }

    private int retry;


//    public final static String dirPath = "C:\\Users\\meng\\Desktop\\novel";
    public final static String dirPath = "home" + File.separator + "data" + File.separator + "novel";

    private final static novelReptile lock = new novelReptile();

    private Integer chapterIndex;

    private String chapterName;

    private String next;


    NovelDao novelDao;

    NovelCopyDao novelCopyDao;

    @Transactional(propagation = Propagation.NEVER)
    public void getFromIndex(String url, String start, String novelName) {

        List<Novel> list = novelDao.selectList(new LambdaQueryWrapper<Novel>().eq(Novel::getNovelName, novelName));
        Novel novel;
        if (CollectionUtils.isEmpty(list)) {
            novel = new Novel().setNovelName(novelName).setStatus("获取中").setChapterNum(0);
            novelDao.insert(novel);
        } else {
            novel = list.get(0);
            if ("获取失败!".equals(novel.getStatus())) {
                novelDao.updateById(novel.setStatus("获取中"));
            }
        }
        next = start;
        FileWriter fileWriter = null;
        try {
            File dir = new File(dirPath + File.separator + novelName);
            dir.mkdirs();
            fileWriter = new FileWriter(dirPath + File.separator + novelName + File.separator + novelName + ".txt", true);
            do {
                synchronized (lock) {
                    String address = url + next;
                    Document parse = Jsoup.connect(address).get();
                    StringBuilder content = new StringBuilder(parse.getElementsByClass("bookname").first().getElementsByTag("h1").text());
                    String bookName = content.toString();
                    chapterName = bookName;
                    content.append('\n').append(parse.getElementById("content").text()).append('\n').append('\n');
                    fileWriter.write(content.toString());

                    Elements aTag = parse.getElementsByClass("bottem1").first().getElementsByTag("a");
                    List<Element> collect = aTag.stream().filter(tag -> "下一章".equals(tag.text())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(collect)) {
                        next = collect.get(0).attr("href");
                        if(next.contains("/")){
                            next = "";
                        }
                    } else {
                        next = "";
                    }
                    log.info("正在获取----" + bookName + "---href:" + next);
                    chapterIndex++;
                    if (chapterIndex % 50 == 0) {
                        novelDao.updateById(novel.setLatestChapter(chapterName).setChapterNum(novel.getChapterNum()+chapterIndex));
                        chapterIndex=0;
                    }
                }
                Thread.sleep(2000);
            } while (StringUtils.isNotBlank(next));
            novelDao.updateById(novel.setNovelName(novelName).setStatus("已完成").setChapterNum(chapterIndex).setLatestChapter(chapterName));
        } catch (Exception e) {
            e.printStackTrace();
            novelDao.updateById(novel.setChapterNum(chapterIndex+novel.getChapterNum()).setLatestChapter(chapterName));
            chapterIndex=0;
            if (retry < 10) {
                novelReptile novelReptile = new novelReptile(chapterIndex, chapterName, novelDao, novelCopyDao, ++retry);
                log.error("第" + retry + "次重复尝试下载" + novelName);
                ThreadPoolUtils.run(() -> {
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException interruptedException) {
                        interruptedException.printStackTrace();
                    }
                    novelReptile.getFromIndex(url, next, novelName);
                });
            } else {
                novelDao.updateById(novel.setStatus("获取失败!"));
            }
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e2) {
                e2.printStackTrace();
            }
        }
    }


}
